/*
 * Copyright (C) 2005 - 2013 MaNGOS <http://www.getmangos.com/>
 *
 * Copyright (C) 2008 - 2013 Trinity <http://www.trinitycore.org/>
 *
 * Copyright (C) 2010 - 2013 ProjectSkyfire <http://www.projectskyfire.org/>
 *
 * Copyright (C) 2011 - 2013 ArkCORE <http://www.arkania.net/>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef __BATTLEGROUNDSA_H
#define __BATTLEGROUNDSA_H

class Battleground;

class BattlegroundSAScore: public BattlegroundScore
{
public:
    BattlegroundSAScore () :
            demolishers_destroyed(0), gates_destroyed(0)
    {
    }
    ;
    virtual ~BattlegroundSAScore ()
    {
    }
    ;
    uint8 demolishers_destroyed;
    uint8 gates_destroyed;
};

#define BG_SA_FLAG_AMOUNT 3
#define BG_SA_DEMOLISHER_AMOUNT 4

enum BG_SA_Status
{
    BG_SA_NOTSTARTED = 0, BG_SA_WARMUP, BG_SA_ROUND_ONE, BG_SA_SECOND_WARMUP, BG_SA_ROUND_TWO, BG_SA_BONUS_ROUND
};

enum BG_SA_GateState
{
    BG_SA_GATE_OK = 1, BG_SA_GATE_DAMAGED = 2, BG_SA_GATE_DESTROYED = 3
};

enum BG_SA_Timers
{
    BG_SA_BOAT_START = 60 * IN_MILLISECONDS, BG_SA_WARMUPLENGTH = 120 * IN_MILLISECONDS, BG_SA_ROUNDLENGTH = 600 * IN_MILLISECONDS
};

enum BG_SA_WorldStates
{
    BG_SA_TIMER_MINS = 3559, BG_SA_TIMER_SEC_TENS = 3560, BG_SA_TIMER_SEC_DECS = 3561, BG_SA_ALLY_ATTACKS = 4352, BG_SA_HORDE_ATTACKS = 4353, BG_SA_PURPLE_GATEWS = 3614, BG_SA_RED_GATEWS = 3617, BG_SA_BLUE_GATEWS = 3620, BG_SA_GREEN_GATEWS = 3623, BG_SA_YELLOW_GATEWS = 3638, BG_SA_ANCIENT_GATEWS = 3849, BG_SA_LEFT_GY_ALLIANCE = 3635, BG_SA_RIGHT_GY_ALLIANCE = 3636, BG_SA_CENTER_GY_ALLIANCE = 3637, BG_SA_RIGHT_ATT_TOKEN_ALL = 3627, BG_SA_LEFT_ATT_TOKEN_ALL = 3626, BG_SA_LEFT_ATT_TOKEN_HRD = 3629, BG_SA_RIGHT_ATT_TOKEN_HRD = 3628, BG_SA_HORDE_DEFENCE_TOKEN = 3631, BG_SA_ALLIANCE_DEFENCE_TOKEN = 3630, BG_SA_RIGHT_GY_HORDE = 3632, BG_SA_LEFT_GY_HORDE = 3633, BG_SA_CENTER_GY_HORDE = 3634, BG_SA_BONUS_TIMER = 0xdf3, BG_SA_ENABLE_TIMER = 3564,
};

enum npc
{
    NPC_ANTI_PERSONNAL_CANNON = 27894, NPC_DEMOLISHER_SA = 28781, NPC_RIGGER_SPARKLIGHT = 29260, NPC_GORGRIL_RIGSPARK = 29262,
};

enum BG_SA_NPCs
{
    BG_SA_GUN_1 = 0, BG_SA_GUN_2, BG_SA_GUN_3, BG_SA_GUN_4, BG_SA_GUN_5, BG_SA_GUN_6, BG_SA_GUN_7, BG_SA_GUN_8, BG_SA_GUN_9, BG_SA_GUN_10, BG_SA_DEMOLISHER_1, BG_SA_DEMOLISHER_2, BG_SA_DEMOLISHER_3, BG_SA_DEMOLISHER_4, BG_SA_NPC_TRIGGER_1, BG_SA_NPC_TRIGGER_2, BG_SA_NPC_TRIGGER_3, BG_SA_NPC_TRIGGER_4, BG_SA_NPC_TRIGGER_5, BG_SA_NPC_SPARKLIGHT, BG_SA_NPC_RIGSPARK, BG_SA_MAXNPC
};

enum BG_SA_Boat
{
    BG_SA_BOAT_ONE_A = 193182, BG_SA_BOAT_TWO_H = 193183, BG_SA_BOAT_ONE_H = 193184, BG_SA_BOAT_TWO_A = 193185,
};

const uint32 BG_SA_NpcEntries[BG_SA_MAXNPC] =
{ NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON,
//4 beach demolishers
NPC_DEMOLISHER_SA, NPC_DEMOLISHER_SA, NPC_DEMOLISHER_SA, NPC_DEMOLISHER_SA,
//Triggers
23472, 23472, 23472, 23472, 23472,
//Used Demolisher Salesman
NPC_RIGGER_SPARKLIGHT, NPC_GORGRIL_RIGSPARK };

const float BG_SA_NpcSpawnlocs[BG_SA_MAXNPC + BG_SA_DEMOLISHER_AMOUNT][4] =
{
//Cannons
{ 1436.429f, 110.05f, 41.407f, 5.4f },
{ 1404.9023f, 84.758f, 41.183f, 5.46f },
{ 1068.693f, -86.951f, 93.81f, 0.02f },
{ 1068.83f, -127.56f, 96.45f, 0.0912f },
{ 1422.115f, -196.433f, 42.1825f, 1.0222f },
{ 1454.887f, -220.454f, 41.956f, 0.9627f },
{ 1232.345f, -187.517f, 66.945f, 0.45f },
{ 1249.634f, -224.189f, 66.72f, 0.635f },
{ 1236.213f, 92.287f, 64.965f, 5.751f },
{ 1215.11f, 57.772f, 64.739f, 5.78f },
//Demolishers
{ 1611.597656f, -117.270073f, 8.719355f, 2.513274f },
{ 1575.562500f, -158.421875f, 5.024450f, 2.129302f },
{ 1618.047729f, 61.424641f, 7.248210f, 3.979351f },
{ 1575.103149f, 98.873344f, 2.830360f, 3.752458f },
//trigger
{ 1453.49f, -250.453f, 30.896f, 4.2883f },
{ 1377.05f, 97.036f, 30.8605f, 2.46539f },
{ 1186.05f, 58.8048f, 56.5491f, 2.75992f },
{ 1042.83f, -72.839f, 84.8145f, 3.58615f },
{ 1233.62f, -250.49f, 55.4036f, 3.7016f },
//Npcs
{ 1348.644165f, -298.786469f, 31.080130f, 1.710423f },
{ 1358.191040f, 195.527786f, 31.018187f, 4.171337f },
//Demolishers2
{ 1371.055786f, -317.071136f, 35.007359f, 1.947460f },
{ 1424.034912f, -260.195190f, 31.084425f, 2.820013f },
{ 1353.139893f, 223.745438f, 35.265411f, 4.343684f },
{ 1404.809570f, 197.027237f, 32.046032f, 3.605401f } };

enum BG_SA_Objects
{
    BG_SA_GREEN_GATE = 0, BG_SA_YELLOW_GATE, BG_SA_BLUE_GATE, BG_SA_RED_GATE, BG_SA_PURPLE_GATE, BG_SA_ANCIENT_GATE, BG_SA_TITAN_RELIC, BG_SA_BOAT_ONE, BG_SA_BOAT_TWO, BG_SA_SIGIL_1, BG_SA_SIGIL_2, BG_SA_SIGIL_3, BG_SA_SIGIL_4, BG_SA_SIGIL_5, BG_SA_CENTRAL_FLAGPOLE, BG_SA_RIGHT_FLAGPOLE, BG_SA_LEFT_FLAGPOLE, BG_SA_CENTRAL_FLAG, BG_SA_RIGHT_FLAG, BG_SA_LEFT_FLAG, BG_SA_PORTAL_DEFFENDER_BLUE, BG_SA_PORTAL_DEFFENDER_GREEN, BG_SA_PORTAL_DEFFENDER_YELLOW, BG_SA_PORTAL_DEFFENDER_PURPLE, BG_SA_PORTAL_DEFFENDER_RED, BG_SA_BOMB, BG_SA_MAXOBJ = BG_SA_BOMB + 68
};

const float BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4] =
{
{ 1411.57f, 108.163f, 28.692f, 5.441f },
{ 1055.452f, -108.1f, 82.134f, 0.034f },
{ 1431.3413f, -219.437f, 30.893f, 0.9736f },
{ 1227.667f, -212.555f, 55.372f, 0.5023f },
{ 1214.681f, 81.21f, 53.413f, 5.745f },
{ 878.555f, -108.2f, 117.845f, 0.0f },
{ 836.5f, -108.8f, 120.219f, 0.0f },
//Ships
{ 2679.696777f, -826.891235f, 3.712860f, 5.78367f },          //rot2 1 rot3 0.0002f
{ 2574.003662f, 981.261475f, 2.603424f, 0.807696f },
//Sigils
{ 1414.054f, 106.72f, 41.442f, 5.441f },
{ 1060.63f, -107.8f, 94.7f, 0.034f },
{ 1433.383f, -216.4f, 43.642f, 0.9736f },
{ 1230.75f, -210.724f, 67.611f, 0.5023f },
{ 1217.8f, 79.532f, 66.58f, 5.745f },
//Flagpoles
{ 1215.114258f, -65.711861f, 70.084267f, -3.124123f },
{ 1338.863892f, -153.336533f, 30.895121f, -2.530723f },
{ 1309.124268f, 9.410645f, 30.893402f, -1.623156f },
//Flags
{ 1215.108032f, -65.715767f, 70.084267f, -3.124123f },
{ 1338.859253f, -153.327316f, 30.895077f, -2.530723f },
{ 1309.192017f, 9.416233f, 30.893402f, 1.518436f },
//Portal
{ 1468.380005f, -225.798996f, 30.896200f, 0.0f },          //blue
{ 1394.270020f, 72.551399f, 31.054300f, 0.0f },          //green
{ 1065.260010f, -89.79501f, 81.073402f, 0.0f },          //yellow
{ 1216.069946f, 47.904301f, 54.278198f, 0.0f },          //purple
{ 1255.569946f, -233.548996f, 56.43699f, 0.0f },          //red
//Bombs
{ 1333.45f, 211.354f, 31.0538f, 5.03666f },
{ 1334.29f, 209.582f, 31.0532f, 1.28088f },
{ 1332.72f, 210.049f, 31.0532f, 1.28088f },
{ 1334.28f, 210.78f, 31.0538f, 3.85856f },
{ 1332.64f, 211.39f, 31.0532f, 1.29266f },
{ 1371.41f, 194.028f, 31.5107f, 0.753095f },
{ 1372.39f, 194.951f, 31.4679f, 0.753095f },
{ 1371.58f, 196.942f, 30.9349f, 1.01777f },
{ 1370.43f, 196.614f, 30.9349f, 0.957299f },
{ 1369.46f, 196.877f, 30.9351f, 2.45348f },
{ 1370.35f, 197.361f, 30.9349f, 1.08689f },
{ 1369.47f, 197.941f, 30.9349f, 0.984787f },
{ 1592.49f, 47.5969f, 7.52271f, 4.63218f },
{ 1593.91f, 47.8036f, 7.65856f, 4.63218f },
{ 1593.13f, 46.8106f, 7.54073f, 4.63218f },
{ 1589.22f, 36.3616f, 7.45975f, 4.64396f },
{ 1588.24f, 35.5842f, 7.55613f, 4.79564f },
{ 1588.14f, 36.7611f, 7.49675f, 4.79564f },
{ 1595.74f, 35.5278f, 7.46602f, 4.90246f },
{ 1596, 36.6475f, 7.47991f, 4.90246f },
{ 1597.03f, 36.2356f, 7.48631f, 4.90246f },
{ 1597.93f, 37.1214f, 7.51725f, 4.90246f },
{ 1598.16f, 35.888f, 7.50018f, 4.90246f },
{ 1579.6f, -98.0917f, 8.48478f, 1.37996f },
{ 1581.2f, -98.401f, 8.47483f, 1.37996f },
{ 1580.38f, -98.9556f, 8.4772f, 1.38781f },
{ 1585.68f, -104.966f, 8.88551f, 0.493246f },
{ 1586.15f, -106.033f, 9.10616f, 0.493246f },
{ 1584.88f, -105.394f, 8.82985f, 0.493246f },
{ 1581.87f, -100.899f, 8.46164f, 0.929142f },
{ 1581.48f, -99.4657f, 8.46926f, 0.929142f },
{ 1583.2f, -91.2291f, 8.49227f, 1.40038f },
{ 1581.94f, -91.0119f, 8.49977f, 1.40038f },
{ 1582.33f, -91.951f, 8.49353f, 1.1844f },
{ 1342.06f, -304.049f, 30.9532f, 5.59507f },
{ 1340.96f, -304.536f, 30.9458f, 1.28323f },
{ 1341.22f, -303.316f, 30.9413f, 0.486051f },
{ 1342.22f, -302.939f, 30.986f, 4.87643f },
{ 1382.16f, -287.466f, 32.3063f, 4.80968f },
{ 1381, -287.58f, 32.2805f, 4.80968f },
{ 1381.55f, -286.536f, 32.3929f, 2.84225f },
{ 1382.75f, -286.354f, 32.4099f, 1.00442f },
{ 1379.92f, -287.34f, 32.2872f, 3.81615f },
{ 1100.52f, -2.41391f, 70.2984f, 0.131054f },
{ 1099.35f, -2.13851f, 70.3375f, 4.4586f },
{ 1099.59f, -1.00329f, 70.238f, 2.49903f },
{ 1097.79f, 0.571316f, 70.159f, 4.00307f },
{ 1098.74f, -7.23252f, 70.7972f, 4.1523f },
{ 1098.46f, -5.91443f, 70.6715f, 4.1523f },
{ 1097.53f, -7.39704f, 70.7959f, 4.1523f },
{ 1097.32f, -6.64233f, 70.7424f, 4.1523f },
{ 1096.45f, -5.96664f, 70.7242f, 4.1523f },
{ 971.725f, 0.496763f, 86.8467f, 2.09233f },
{ 973.589f, 0.119518f, 86.7985f, 3.17225f },
{ 972.524f, 1.25333f, 86.8351f, 5.28497f },
{ 971.993f, 2.05668f, 86.8584f, 5.28497f },
{ 973.635f, 2.11805f, 86.8197f, 2.36722f },
{ 974.791f, 1.74679f, 86.7942f, 1.5936f },
{ 974.771f, 3.0445f, 86.8125f, 0.647199f },
{ 979.554f, 3.6037f, 86.7923f, 1.69178f },
{ 979.758f, 2.57519f, 86.7748f, 1.76639f },
{ 980.769f, 3.48904f, 86.7939f, 1.76639f },
{ 979.122f, 2.87109f, 86.7794f, 1.76639f },
{ 986.167f, 4.85363f, 86.8439f, 1.5779f },
{ 986.176f, 3.50367f, 86.8217f, 1.5779f },
{ 987.33f, 4.67389f, 86.8486f, 1.5779f },
{ 985.23f, 4.65898f, 86.8368f, 1.5779f },
{ 984.556f, 3.54097f, 86.8137f, 1.5779f }, };

/* Ships:
 * 193182 - ally
 * 193183 - horde
 * 193184 - horde
 * 193185 - ally
 * Banners:
 * 191308 - left one,
 * 191306 - right one,
 * 191310 - central,
 * Ally ones, substract 1
 * to get horde ones.
 */

const uint32 BG_SA_ObjEntries[BG_SA_MAXOBJ + BG_SA_FLAG_AMOUNT] =
{ 190722, 190727, 190724, 190726, 190723, 192549, 192834, 0,          // Boat
0,          // Boat
192687, 192685, 192689, 192690, 192691, 191311, 191311, 191311, 191310, 191306, 191308, 192819, 192819, 192819, 192819, 192819, 190753 };

const uint32 BG_SA_Factions[2] =
{ 1732, 1735, };

enum BG_SA_Graveyards
{
    BG_SA_BEACH_GY = 0, BG_SA_DEFENDER_LAST_GY, BG_SA_RIGHT_CAPTURABLE_GY, BG_SA_LEFT_CAPTURABLE_GY, BG_SA_CENTRAL_CAPTURABLE_GY, BG_SA_MAX_GY
};

const uint32 BG_SA_GYEntries[BG_SA_MAX_GY] =
{ 1350, 1349, 1347, 1346, 1348, };

const float BG_SA_GYOrientation[BG_SA_MAX_GY] =
{ 6.202f, 1.926f,          //right capturable GY
3.917f,          //left capturable GY
3.104f,          //center, capturable
6.148f,          //defender last GY
};

struct BG_SA_RoundScore
{
    TeamId winner;
    uint32 time;
};

/// Class for manage Strand of Ancient battleground
class BattlegroundSA: public Battleground
{
    friend class BattlegroundMgr;

public:
    /// Constructor
    BattlegroundSA ();
    /// Destructor
    ~BattlegroundSA ();

    /**
     * \brief Called every time for update battle data
     * -Update timer
     * -Round switch
     */
    void Update (uint32 diff);

    /* inherited from BattlegroundClass */
    /// Called when a player join battle
    virtual void AddPlayer (Player *plr);
    /// Called when battle start
    virtual void StartingEventCloseDoors ();
    virtual void StartingEventOpenDoors ();

    /// Called for ini battleground, after that the first player be entered
    virtual bool SetupBattleground ();
    virtual void Reset ();
    /// Called for generate packet contain worldstate data
    virtual void FillInitialWorldStates (WorldPacket& data);
    /// Called when a player deal damage to building (door)
    virtual void EventPlayerDamagedGO (Player* plr, GameObject* go, uint8 hitType, uint32 destroyedEvent);
    /// Called when a player kill a unit in bg
    virtual void HandleKillUnit (Creature* unit, Player* killer);
    /// Return the nearest graveyard where player can respawn
    virtual WorldSafeLocsEntry const* GetClosestGraveYard (Player* player);
    /// Called when a player click on flag (graveyard flag)
    virtual void EventPlayerClickedOnFlag (Player *Source, GameObject* target_obj);
    /// Called when a player use a gamobject (relic)
    virtual void EventPlayerUsedGO (Player* Source, GameObject* object);
    /// Return gate id, relative to bg data, according to gameobject id
    uint32 GetGateIDFromDestroyEventID (uint32 id)
    {
        uint32 i = 0;
        switch (id)
        {
        case 19046:
            i = BG_SA_GREEN_GATE;
            break;          //Green gate destroyed
        case 19045:
            i = BG_SA_BLUE_GATE;
            break;          //blue gate
        case 19047:
            i = BG_SA_RED_GATE;
            break;          //red gate
        case 19048:
            i = BG_SA_PURPLE_GATE;
            break;          //purple gate
        case 19049:
            i = BG_SA_YELLOW_GATE;
            break;          //yellow gate
        case 19837:
            i = BG_SA_ANCIENT_GATE;
            break;          //ancient gate
        }
        return i;
    }
    /// Return worldstate id, according to door id
    uint32 GetWorldStateFromGateID (uint32 id)
    {
        uint32 uws = 0;
        switch (id)
        {
        case BG_SA_GREEN_GATE:
            uws = BG_SA_GREEN_GATEWS;
            break;
        case BG_SA_YELLOW_GATE:
            uws = BG_SA_YELLOW_GATEWS;
            break;
        case BG_SA_BLUE_GATE:
            uws = BG_SA_BLUE_GATEWS;
            break;
        case BG_SA_RED_GATE:
            uws = BG_SA_RED_GATEWS;
            break;
        case BG_SA_PURPLE_GATE:
            uws = BG_SA_PURPLE_GATEWS;
            break;
        case BG_SA_ANCIENT_GATE:
            uws = BG_SA_ANCIENT_GATEWS;
            break;
        }
        return uws;
    }

    /// Called on battleground ending
    void EndBattleground (uint32 winner);

    /// CAlled when a player leave battleground
    void RemovePlayer (Player *plr, uint64 guid);
    void HandleAreaTrigger (Player *Source, uint32 Trigger);

    /* Scorekeeping */
    /// Update score board
    //uint32 GetPlayerDemolisherScore(Player* /*source*/);  // Future use
    void UpdatePlayerScore (Player *Source, uint32 type, uint32 value, bool doAddHonor = true);

private:

    /**
     * \brief Called on setup and between the two round
     * -Delete all gameobject / creature
     * -Respawn all gameobject / creature to have good faction
     */
    bool ResetObjs ();
    /// Called for start ship movement
    void StartShips ();
    /**
     * \brief Called between the two round
     * -Teleport all players to good location
     */
    void TeleportPlayers ();
    /**
     * \brief Called on start and between the two round
     * -Update faction of all vehicle
     */
    void OverrideGunFaction ();
    /// Set selectable or not demolisher, called on battle start, when boats arrive to dock
    void DemolisherStartState (bool start);
    /**
     * \brief Called when a gate is destroy
     * -Give honor to player witch destroy it
     * -Update worldstate
     * -Delete gameobject in front of door (lighting object, with different colours for each door)
     */
    void DestroyGate (Player* pl, GameObject* /*go*/, uint32 destroyedEvent);
    /// Update timer worldstate
    void SendTime ();
    /**
     * \brief Called when a graveyard is capture
     * -Update spiritguide
     * -Update gameobject (flag)
     * -Update Worldstate
     * -Send warning for announce this
     * \param i : id of graveyard
     * \param Source : Player who capture gy
     */
    void CaptureGraveyard (BG_SA_Graveyards i, Player *Source);
    /// Switch on/off timer worldstate
    void ToggleTimer ();

    /// Respawn dead demolisher
    void UpdateDemolisherSpawns ();

    /// Send packet to player for create boats (client part)
    void SendTransportInit (Player *player);
    /// Send packet to player for destroy boats (client part)
    void SendTransportsRemove (Player * player);

    /// Id of attacker team
    TeamId Attackers;
    /// Total elapsed time of current round
    uint32 TotalTime;
    /// Max time of round
    uint32 EndRoundTimer;
    /// For know if boats has start moving or not yet
    bool ShipsStarted;
    /// Status of each gate (Destroy/Damage/Intact)
    BG_SA_GateState GateStatus[6];
    /// Status of battle (Start or not, and what round)
    BG_SA_Status Status;
    /// Team witch control each graveyard
    TeamId GraveyardStatus[BG_SA_MAX_GY];
    /// Score of each round
    BG_SA_RoundScore RoundScores[2];
    /// used for know we are in timer phase or not (used for worldstate update)
    bool TimerEnabled;
    /// 5secs before starting the 1min countdown for second round
    uint32 UpdateWaitTimer;
    /// for know if warning about second round start has been sent
    bool SignaledRoundTwo;
    /// for know if warning about second round start has been sent
    bool SignaledRoundTwoHalfMin;
    /// for know if second round has been init
    bool InitSecondRound;
    std::map<uint32/*id*/, uint32/*timer*/> DemoliserRespawnList;
};
#endif
